Improve guest time keeping
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Mon, 25 Jul 2005 21:03:40 +0000 (21:03 +0000)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Mon, 25 Jul 2005 21:03:40 +0000 (21:03 +0000)
Even though we accounted for lost ticks, the accounting was not precise.
Specifically, we didn't account for the delay in calling the ac_timer
handler.

Signed-off-by: Eddie Dong <eddie.dong@intel.com>
Signed-off-by: Arun Sharma <arun.sharma@intel.com>
xen/arch/x86/vmx_intercept.c
xen/include/asm-x86/vmx_virpit.h

index 15b8caf371b8a0a794a9a663da835ec8c47eb434..4252d923fa10138b996cf3474fc840e1b9e757a8 100644 (file)
@@ -197,12 +197,23 @@ int intercept_pit_io(ioreq_t *p)
 static void pit_timer_fn(void *data)
 {
     struct vmx_virpit_t *vpit = data;
+    s_time_t   next;
+    int        missed_ticks;
+
+    missed_ticks = (NOW() - vpit->scheduled) / MILLISECS(vpit->period);
 
     /* Set the pending intr bit, and send evtchn notification to myself. */
     if (test_and_set_bit(vpit->vector, vpit->intr_bitmap))
         vpit->pending_intr_nr++; /* already set, then count the pending intr */
 
-    set_ac_timer(&vpit->pit_timer, NOW() + MILLISECS(vpit->period));
+    /* pick up missed timer tick */
+    if ( missed_ticks > 0 ) {
+        vpit->pending_intr_nr+= missed_ticks;
+        vpit->scheduled += missed_ticks * MILLISECS(vpit->period);
+    }
+    next = vpit->scheduled + MILLISECS(vpit->period);
+    set_ac_timer(&vpit->pit_timer, next);
+    vpit->scheduled = next;
 }
 
 
@@ -263,7 +274,8 @@ void vmx_hooks_assist(struct vcpu *d)
 
         vpit->intr_bitmap = intr;
 
-       set_ac_timer(&vpit->pit_timer, NOW() + MILLISECS(vpit->period));
+        vpit->scheduled = NOW() + MILLISECS(vpit->period);
+        set_ac_timer(&vpit->pit_timer, vpit->scheduled);
 
         /*restore the state*/
         p->state = STATE_IORESP_READY;
index 6a0a4edab72ca48f03ea7e30ead260e428f406dd..64bf9e19f054002d0095f0af4a2239c8a5c0ec8c 100644 (file)
@@ -19,6 +19,7 @@ struct vmx_virpit_t {
     /* for simulation of counter 0 in mode 2*/
     int vector;                                /* the pit irq vector */
     unsigned int period;               /* the frequency. e.g. 10ms*/
+    s_time_t scheduled;                 /* scheduled timer interrupt */
     unsigned int channel;              /* the pit channel, counter 0~2 */
     u64  *intr_bitmap;
     unsigned int pending_intr_nr;      /* the couner for pending timer interrupts */